﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace FlowNodeFramework.UC
{
    /// <summary>  
    /// XNode.xaml 的交互逻辑  
    /// </summary>  
    public partial class XNode : UserControl
    {
        #region 构造函数
        public XNode()
        {
            InitializeComponent();
            MouseEnter += XNode_MouseEnter;
            MouseLeave += XNode_MouseLeave;
        }
        #endregion

        #region 成员属性

        public Border InputNodeRef => this.InputNode;
        public Border OutputNodeRef => this.OutputNode;

        private bool focused;

        public bool Focused
        {
            get { return focused; }
            set
            {
                focused = value;
                if (value)
                {
                    BorderVisible = Visibility.Visible;
                    method1();
                }
                else
                {
                    BorderVisible = Visibility.Collapsed;
                    method2();
                }
            }
        }


        #endregion

        #region 依赖属性
        public Brush HeaderBkColor
        {
            get { return (Brush)GetValue(HeaderBkColorProperty); }
            set { SetValue(HeaderBkColorProperty, value); }
        }

        public static readonly DependencyProperty HeaderBkColorProperty =
            DependencyProperty.Register("HeaderBkColor", typeof(Brush), typeof(XNode),
                new PropertyMetadata(new SolidColorBrush((Color)ColorConverter.ConvertFromString("#7160E8"))));

        public Brush HeaderForeColor
        {
            get { return (Brush)GetValue(HeaderForeColorProperty); }
            set { SetValue(HeaderForeColorProperty, value); }
        }

        public static readonly DependencyProperty HeaderForeColorProperty =
            DependencyProperty.Register("HeaderForeColor", typeof(Brush), typeof(XNode),
                new PropertyMetadata(new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FFFFFF"))));

        public Brush BackColor
        {
            get { return (Brush)GetValue(BackColorProperty); }
            set { SetValue(BackColorProperty, value); }
        }

        public static readonly DependencyProperty BackColorProperty =
            DependencyProperty.Register("BackColor", typeof(Brush), typeof(XNode), new PropertyMetadata(new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FFFFFF"))));


        public object Content
        {
            get { return (object)GetValue(ContentProperty); }
            set { SetValue(ContentProperty, value); }
        }

        public static readonly DependencyProperty ContentProperty =
            DependencyProperty.Register("Content", typeof(object), typeof(XNode), new PropertyMetadata(""));


        /// <summary>
        /// 边界线宽
        /// </summary>
        public double LineWidth
        {
            get { return (double)GetValue(LineWidthProperty); }
            set { SetValue(LineWidthProperty, value); }
        }

        public static readonly DependencyProperty LineWidthProperty =
            DependencyProperty.Register("LineWidth", typeof(double), typeof(XNode), new PropertyMetadata(3d));


        /// <summary>
        /// 缩进量
        /// </summary>

        public double Shrink
        {
            get { return (double)GetValue(ShrinkProperty); }
            set { SetValue(ShrinkProperty, value); }
        }

        public static readonly DependencyProperty ShrinkProperty =
            DependencyProperty.Register("Shrink", typeof(double), typeof(XNode), new PropertyMetadata(8d));

        /// <summary>
        /// 边框是否可见
        /// </summary>

        public Visibility BorderVisible
        {
            get { return (Visibility)GetValue(BorderVisibleProperty); }
            set { SetValue(BorderVisibleProperty, value); }
        }

        public static readonly DependencyProperty BorderVisibleProperty =
            DependencyProperty.Register("BorderVisible", typeof(Visibility), typeof(XNode), new PropertyMetadata(Visibility.Collapsed));

        #endregion

        #region 自定义事件
        //private event EventHandler<MouseButtonEventArgs> _leftPortMouseLeftBtnUp;
        //public event EventHandler<MouseButtonEventArgs> LeftPortMouseLeftBtnUp
        //{
        //    add { _leftPortMouseLeftBtnUp += value; }
        //    remove { _leftPortMouseLeftBtnUp -= value; }
        //}

        //private event EventHandler<MouseButtonEventArgs> _rightPortMouseRightBtnDown;
        //public event EventHandler<MouseButtonEventArgs> RightPortMouseRightBtnDown
        //{
        //    add { _rightPortMouseRightBtnDown += value; }
        //    remove { _rightPortMouseRightBtnDown -= value; }
        //}

        private event EventHandler<MouseButtonEventArgs> _headerMouseLeftBtnDown;
        public event EventHandler<MouseButtonEventArgs> HeaderMouseLeftBtnDown
        {
            add { _headerMouseLeftBtnDown += value; }
            remove { _headerMouseLeftBtnDown -= value; }
        }

        private event EventHandler<MouseEventArgs> _headerMove;
        public event EventHandler<MouseEventArgs> HeaderMove
        {
            add { _headerMove += value; }
            remove { _headerMove -= value; }
        }

        private event EventHandler<MouseButtonEventArgs> _headerMouseLeftBtnUp;
        public event EventHandler<MouseButtonEventArgs> HeaderMouseLeftBtnUp
        {
            add { _headerMouseLeftBtnUp += value; }
            remove { _headerMouseLeftBtnUp -= value; }
        }
        #endregion

        #region 控件本地事件

        private void HeaderMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            _headerMouseLeftBtnDown?.Invoke(this, e);
        }

        private void HeaderMouseMove(object sender, MouseEventArgs e)
        {
            _headerMove?.Invoke(sender, e);
        }

        private void HeaderMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            _headerMouseLeftBtnUp?.Invoke(sender, e);
        }

        private void XNode_MouseEnter(object sender, MouseEventArgs e)
        {
            BorderVisible = Visibility.Visible;
            method1();
        }

        private void XNode_MouseLeave(object sender, MouseEventArgs e)
        {
            if (Focused) return;
            method2();
            BorderVisible = Visibility.Collapsed;
        }
        #endregion

        #region 本地方法
        /// <summary>
        /// 收缩动画
        /// </summary>
        private void method1()
        {
            Thickness t1 = new Thickness(Shrink, Shrink, 0, 0);
            Thickness t2 = new Thickness(0, Shrink, Shrink, 0);
            Thickness t3 = new Thickness(Shrink, 0, 0, Shrink);
            Thickness t4 = new Thickness(0, 0, Shrink, Shrink);

            ThicknessAnimation animation1 = new ThicknessAnimation(t1, TimeSpan.FromMilliseconds(200));
            ThicknessAnimation animation2 = new ThicknessAnimation(t2, TimeSpan.FromMilliseconds(200));
            ThicknessAnimation animation3 = new ThicknessAnimation(t3, TimeSpan.FromMilliseconds(200));
            ThicknessAnimation animation4 = new ThicknessAnimation(t4, TimeSpan.FromMilliseconds(200));

            ColorAnimation colorAnimation1 = new ColorAnimation(Colors.Goldenrod, TimeSpan.FromMilliseconds(200));
            ColorAnimation colorAnimation2 = new ColorAnimation(Colors.Goldenrod, TimeSpan.FromMilliseconds(200));
            ColorAnimation colorAnimation3 = new ColorAnimation(Colors.Goldenrod, TimeSpan.FromMilliseconds(200));
            ColorAnimation colorAnimation4 = new ColorAnimation(Colors.Goldenrod, TimeSpan.FromMilliseconds(200));


            Storyboard storyboard = new Storyboard();
            storyboard.Children.Add(animation1);
            storyboard.Children.Add(animation2);
            storyboard.Children.Add(animation3);
            storyboard.Children.Add(animation4);

            storyboard.Children.Add(colorAnimation1);
            storyboard.Children.Add(colorAnimation2);
            storyboard.Children.Add(colorAnimation3);
            storyboard.Children.Add(colorAnimation4);

            Storyboard.SetTarget(animation1, p1);
            Storyboard.SetTarget(animation2, p2);
            Storyboard.SetTarget(animation3, p3);
            Storyboard.SetTarget(animation4, p4);

            Storyboard.SetTarget(colorAnimation1, p1);
            Storyboard.SetTarget(colorAnimation2, p2);
            Storyboard.SetTarget(colorAnimation3, p3);
            Storyboard.SetTarget(colorAnimation4, p4);

            Storyboard.SetTargetProperty(animation1, new PropertyPath("Margin"));
            Storyboard.SetTargetProperty(animation2, new PropertyPath("Margin"));
            Storyboard.SetTargetProperty(animation3, new PropertyPath("Margin"));
            Storyboard.SetTargetProperty(animation4, new PropertyPath("Margin"));

            Storyboard.SetTargetProperty(colorAnimation1, new PropertyPath("(Shape.Stroke).(SolidColorBrush.Color)"));
            Storyboard.SetTargetProperty(colorAnimation2, new PropertyPath("(Shape.Stroke).(SolidColorBrush.Color)"));
            Storyboard.SetTargetProperty(colorAnimation3, new PropertyPath("(Shape.Stroke).(SolidColorBrush.Color)"));
            Storyboard.SetTargetProperty(colorAnimation4, new PropertyPath("(Shape.Stroke).(SolidColorBrush.Color)"));

            storyboard.Begin();
        }

        /// <summary>
        /// 扩展动画
        /// </summary>
        private void method2()
        {
            Thickness t1 = new Thickness(0);
            Thickness t2 = new Thickness(0);
            Thickness t3 = new Thickness(0);
            Thickness t4 = new Thickness(0);

            ThicknessAnimation animation1 = new ThicknessAnimation(t1, TimeSpan.FromMilliseconds(200));
            ThicknessAnimation animation2 = new ThicknessAnimation(t2, TimeSpan.FromMilliseconds(200));
            ThicknessAnimation animation3 = new ThicknessAnimation(t3, TimeSpan.FromMilliseconds(200));
            ThicknessAnimation animation4 = new ThicknessAnimation(t4, TimeSpan.FromMilliseconds(200));

            ColorAnimation colorAnimation1 = new ColorAnimation(Colors.Blue, TimeSpan.FromMilliseconds(200));
            ColorAnimation colorAnimation2 = new ColorAnimation(Colors.Blue, TimeSpan.FromMilliseconds(200));
            ColorAnimation colorAnimation3 = new ColorAnimation(Colors.Blue, TimeSpan.FromMilliseconds(200));
            ColorAnimation colorAnimation4 = new ColorAnimation(Colors.Blue, TimeSpan.FromMilliseconds(200));

            Storyboard storyboard = new Storyboard();
            storyboard.Children.Add(animation1);
            storyboard.Children.Add(animation2);
            storyboard.Children.Add(animation3);
            storyboard.Children.Add(animation4);

            storyboard.Children.Add(colorAnimation1);
            storyboard.Children.Add(colorAnimation2);
            storyboard.Children.Add(colorAnimation3);
            storyboard.Children.Add(colorAnimation4);

            Storyboard.SetTarget(animation1, p1);
            Storyboard.SetTarget(animation2, p2);
            Storyboard.SetTarget(animation3, p3);
            Storyboard.SetTarget(animation4, p4);

            Storyboard.SetTarget(colorAnimation1, p1);
            Storyboard.SetTarget(colorAnimation2, p2);
            Storyboard.SetTarget(colorAnimation3, p3);
            Storyboard.SetTarget(colorAnimation4, p4);

            Storyboard.SetTargetProperty(animation1, new PropertyPath("Margin"));
            Storyboard.SetTargetProperty(animation2, new PropertyPath("Margin"));
            Storyboard.SetTargetProperty(animation3, new PropertyPath("Margin"));
            Storyboard.SetTargetProperty(animation4, new PropertyPath("Margin"));

            Storyboard.SetTargetProperty(colorAnimation1, new PropertyPath("(Shape.Stroke).(SolidColorBrush.Color)"));
            Storyboard.SetTargetProperty(colorAnimation2, new PropertyPath("(Shape.Stroke).(SolidColorBrush.Color)"));
            Storyboard.SetTargetProperty(colorAnimation3, new PropertyPath("(Shape.Stroke).(SolidColorBrush.Color)"));
            Storyboard.SetTargetProperty(colorAnimation4, new PropertyPath("(Shape.Stroke).(SolidColorBrush.Color)"));

            storyboard.Begin();
        }
        #endregion
    }
}